#include "Creature.h"
#include <time.h>
#include "PlayerMgr.h"
#include "LogicService.h"
#include "Scene/SceneMgr.h"
#include "Character/CreatureMgr.h"
#include "ProtoBuffer/AllProtocol.h"

#include "Character/npc/Npc.h"
#include "Character/newAI/behaviac/CreatureCommonAI.h"
#include "Character/newAI/behaviac/BehaviacAIManager.h"
#include "base/core/Profiler.h"
#include "PlaneMgr/PlaneMgr.h"
#include "Common/AttrMgr/AttrMgr.h"
#include "Common/CampDefine.h"
#include "Common/TableData/AreaAreaCfg.h"
#include "Character/monster/MonsterRefCfg.h"


 uint32_t g_constSendClientCreatureNum = 100;  //每条消息最大人数数据控制,以免视野人数过多，造成消息长度大于底层控制长度
 //生物关系值

 //生物之间关系表格
static int gCreatureVsCreature[FIREND_SHIP_MAX][FIREND_SHIP_MAX] =

 {
		 	 	 	 	 	 	 /*0PLAYER_NONE*/ /*1MONSTER_NONE*/ /*2REBOT_NONE*/ /*3CREATURE_NO_BE_ATTACK*/ /*4PLAYER_CAMP_LIGHT*/ /*5MONSTER_CAMP_LIGHT*/ /*6NPC_CAMP_LIGHT*/ /*7PLAYER_CAMP_DRAK*/ 		/*8MONSTER_CAMP_DARK*/ /*9NPC_CAMP_DARK*/ 		/*10MONSTER_TA*/ 	/*11MONSTER_CAN_BE_DESTROYED*/ /*12MONSTER_TRIGGER_ALL*/	 /*13MONSTER_TRIGGER_PLAYER*/  /*14MONSTER_TRIGGER_MONSTER*/ /*15MONSTER_TRIGGER_NPC*/ /*16MONSTER_NONE_TRAP*/ /*17MONSTER_LIGHT_TRAP */ 			/*18MONSTER_DARK_TRAP*/ /*19MONSTER_NONE_USE_THING*/ 			/*20MONSTER_LIGHT_USE_THING*/ 	/*21MONSTER_DARK_USE_THING*/
/*0PLAYER_NONE*/					{true,				false,			false,				true,					true,						false,				true,				true,						false,					true,					true,						false,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*1MONSTER_NONE*/					{false,				true,			true,				true,					false,						true,				true,				false,						true,					true,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*2REBOT_NONE*/						{false,				true,			true,				true,					false,						true,				true,				false,						true,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*3CREATURE_NO_BE_ATTACK*/  		{true,				true,			true,				true,					true,						true,				true,				true,						true,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*4PLAYER_CAMP_LIGHT*/				{true,				false,			false,				true,					true,						true,				true,				false,						false,					false,					true,						false,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*5MONSTER_CAMP_LIGHT*/				{false,				true,			true,				true,					true,						true,				true,				false,						false,					false,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*6NPC_CAMP_LIGHT*/					{true,				true,			true,				true,					true,						true,				true,				false,						false,					false,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*7PLAYER_CAMP_DARK*/				{true,				false,			false,				true,					false,						false,				false,				true,						true,					true,					true,						false,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*8MONSTER_CAMP_DARK*/				{false,				true,			true,				true,					false,						false,				false,				true,						true,					true,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*9NPC_CAMP_DARK*/					{true,				true,			false,				true,					false,						false,				false,				true,						true,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*10MONSTER_TA*/					{true,				false,			true,				true,					true,						false,				true,				true,						false,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*11MONSTER_BE_DESTROYED*/			{true,				true,			true,				true,					true,						true,				true,				true,						true,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*12MONSTER_TRIGGER_ALL*/			{false,				false,			true,				true,					false,						false,				false,				false,						false,					false,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*13MONSTER_TRIGGER_PLAYER*/		{false,				true,			true,				true,					false,						true,				true,				false,						true,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*14MONSTER_TRIGGER_MONSTER*/		{true,				false,			true,				true,					true,						false,				true,				true,						false,					true,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*15MONSTER_TRIGGER_NPC*/			{true,				true,			true,				true,					true,						true,				false,				true,						true,					false,					true,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*16MONSTER_NONE_TRAP*/				{false,				true,			true,				true,					false,						false,				false,				false,						false,					false,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*17MONSTER_LIGHT_TRAP*/			{false,				false,			true,				true,					true,						true,				true,				false,						false,					false,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*18MONSTER_DARK_TRAP*/				{false,				false,			true,				true,					false,						false,				false,				true,						true,					true,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*19MONSTER_NONE_USE_THING*/ 		{false,				true,			true,				true,					false,						false,				false,				false,						false,					false,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*20MONSTER_LIGHT_USE_THING*/ 		{false,				false,			true,				true,					true,						true,				true,				false,						false,					false,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
/*21MONSTER_DARK_USE_THING*/ 		{false,				false,			true,				true,					false,						false,				false,				true,						true,					true,					false,						true,						true,						true,							true,						true,							true,					true,							true,						true,									true,							true},
};

bool gGetCreatureVsCreature(int first, int second)
{
	if (first < 0 || second < 0 || first >= FIREND_SHIP_MAX || second >= FIREND_SHIP_MAX) return true;

	return gCreatureVsCreature[first][second];
}

int gGetCreatureFriendShip(Creature* pCreature)
{
	if (pCreature->CreatureKind() == CREATURE_PLAYER)
	{
		if (pCreature->GetAttr(C_CAMP_ID) == 0)
		{
			return PLAYER_NONE;
		}
		else if (pCreature->GetAttr(C_CAMP_ID) == 1)
		{
			return PLAYER_CAMP_LIGHT;
		}
		else if (pCreature->GetAttr(C_CAMP_ID) == 2)
		{
			return PLAYER_CAMP_DARK;
		}
		return PLAYER_NONE;
	}
	else if (pCreature->CreatureKind() == CREATURE_NPC)
	{
		Npc* pNpc = dynamic_cast<Npc*>(pCreature);
		if (pNpc)
		{
			if (pNpc->GetNpcInfo()->npcCamp == 0)
			{
				return CREATURE_NO_BE_ATTACK;
			}
			else if (pNpc->GetNpcInfo()->npcCamp == 1)
			{
				return NPC_CAMP_LIGHT;
			}
			else if (pNpc->GetNpcInfo()->npcCamp == 2)
			{
				return NPC_CAMP_DARK;
			}
		}
		return CREATURE_NO_BE_ATTACK;
	}
	else if (pCreature->CreatureKind() == CREATURE_MONSTER)
	{
		Monster* pMonster = dynamic_cast<Monster*>(pCreature);
		if (pMonster)
		{
			if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MONSTER
					|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_NO_MOVE_BOSS
					|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_BOSS_ZHONGSHEN
					|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TRAP_CAN_BE_ATTATED)
			{
				if (pMonster->GetMonsterCampID() == 0)
				{
					return MONSTER_NONE;
				}
				else if (pMonster->GetMonsterCampID() == 1)
				{
					return MONSTER_CAMP_LIGHT;
				}
				else if (pMonster->GetMonsterCampID() == 2)
				{
					return MONSTER_CAMP_DARK;
				}
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_TA)
			{
				return MONSTER_TA;
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
			{
				if (pMonster->GetMonsterMasterKind() == CREATURE_PLAYER)
				{
					if (pMonster->GetMonsterCampID() == 0)
					{
						return PLAYER_NONE;
					}
					else if (pMonster->GetMonsterCampID() == 1)
					{
						return PLAYER_CAMP_LIGHT;
					}
					else if (pMonster->GetMonsterCampID() == 2)
					{
						return PLAYER_CAMP_DARK;
					}
				}
				else if (pMonster->GetMonsterMasterKind() == CREATURE_MONSTER)
				{
					if (pMonster->GetMonsterCampID() == 0)
					{
						return MONSTER_NONE;
					}
					else if (pMonster->GetMonsterCampID() == 1)
					{
						return MONSTER_CAMP_LIGHT;
					}
					else if (pMonster->GetMonsterCampID() == 2)
					{
						return MONSTER_CAMP_DARK;
					}
				}
				else if (pMonster->GetMonsterMasterKind() == CREATURE_NPC)
				{
					if (pMonster->GetMonsterCampID() == 0)
					{
						return CREATURE_NO_BE_ATTACK;
					}
					else if (pMonster->GetMonsterCampID() == 1)
					{
						return NPC_CAMP_LIGHT;
					}
					else if (pMonster->GetMonsterCampID() == 2)
					{
						return NPC_CAMP_DARK;
					}
				}
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_DESTROYED_THING)
			{
				return MONSTER_CAN_BE_DESTROYED;
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_USE_DROP)
			{
				return CREATURE_NO_BE_ATTACK;
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRIGGER_THING)
			{
				if (pMonster->GetMonsterFightType() == TRIGGLE_MONSTER_TYPE_TARGET_EVERYTHING)
				{
					return MONSTER_TRIGGER_ALL;
				}
				else if (pMonster->GetMonsterFightType() == TRIGGLE_MONSTER_TYPE_TARGET_PLAYER)
				{
					return  MONSTER_TRIGGER_PLAYER;
				}
				else if (pMonster->GetMonsterFightType() == TRIGGLE_MONSTER_TYPE_TARGET_MONSTER)
				{
					 return  MONSTER_TRIGGER_MONSTER;
				}
				else if (pMonster->GetMonsterFightType() == TRIGGLE_MONSTER_TYPE_TARGET_NPC)
				{
					 return  MONSTER_TRIGGER_NPC;
				}
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_TRAP)
			{
				if (pMonster->GetMonsterCampID() == 0)
				{
					return MONSTER_NONE_TRAP;
				}
				else if (pMonster->GetMonsterCampID() == 1)
				{
					return MONSTER_CAMP_LIGHT_TRAP;
				}
				else if (pMonster->GetMonsterCampID() == 2)
				{
					return MONSTER_CAMP_DARK_TRAP;
				}
			}
			else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_CAN_USE_THING)
			{
				if (pMonster->GetMonsterCampID() == 0)
				{
					return MONSTER_NONE_USE_THING;
				}
				else if (pMonster->GetMonsterCampID() == 1)
				{
					return MONSTER_CAMP_LIGHT_USE_THING;
				}
				else if (pMonster->GetMonsterCampID() == 2)
				{
					return MONSTER_CAMP_DARK_USE_THING;
				}
			}
			return MONSTER_NONE;
		}
		return MONSTER_NONE;
	}
	else if (pCreature->CreatureKind() == CREATURE_REBOT)
	{
		return REBOT_NONE;
	}
	return CREATURE_NO_BE_ATTACK;
}

CreatureVisionData::CreatureVisionData()
{
	chVisionUnitType = (char)VISIONTYPE_NONE;
}

CreatureVisionData::~CreatureVisionData()
{
	for(DoubleNode* pNode = m_doublePVPSeeLst.Head(); pNode != nullptr; )
	{
		DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
		DoubleNode* precv = pNode;
		pNode = m_doublePVPSeeLst.Next(pNode);
		//m_doublePVPSeeLst.Delete(precv);
		//delete precv;
		//delete pData;
		g_GetCreatureMgr()->RecycleDoubleListView(pData);
		g_GetCreatureMgr()->RecycleDoubleNode(precv);
	}
	m_doublePVPSeeLst.Clear();
	for(DoubleNode* pNode = m_doublePVMSeeLst.Head(); pNode != nullptr; )
	{
		DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
		DoubleNode* precv = pNode;
		pNode = m_doublePVMSeeLst.Next(pNode);
		//m_doublePVMSeeLst.Delete(precv);
		//delete precv;
		//delete pData;

		g_GetCreatureMgr()->RecycleDoubleListView(pData);
		g_GetCreatureMgr()->RecycleDoubleNode(precv);
	}
	m_doublePVMSeeLst.Clear();
}


DoubleNode* CreatureVisionData::AddPVPSeeList(int list, Creature* pCreature)
{
	DoubleListViewData *data = g_GetCreatureMgr()->GetDoublelistView();
	DoubleNode* node = g_GetCreatureMgr()->GetDoubleNode();
	node->SetHost(data);
	data->pCreature = pCreature;
	m_doublePVPSeeLst.InsertTail(node);
	return node;
}

DoubleNode* CreatureVisionData::AddPVMSeeList(Creature* pCreature)
{
	DoubleListViewData *data = g_GetCreatureMgr()->GetDoublelistView();
	DoubleNode* node = g_GetCreatureMgr()->GetDoubleNode();
	node->SetHost(data);

	//data->cid = cid;
	data->pCreature = pCreature;
	m_doublePVMSeeLst.InsertTail(node);
	return node;
}

bool CreatureVisionData::DelPVMSeeList(DoubleNode* node)
{
	if (m_doublePVMSeeLst.Delete(node))
	{
		g_GetCreatureMgr()->RecycleDoubleListView((DoubleListViewData*)node->GetHost());
		g_GetCreatureMgr()->RecycleDoubleNode(node);
		//delete (DoubleListViewData*)node->GetHost();
		//delete node;
		return true;
	}
	return false;
}

bool CreatureVisionData::DelPVPSeeList(DoubleNode* node)
{
	if (m_doublePVPSeeLst.Delete(node))
	{
		//delete (DoubleListViewData*)node->GetHost();
		//delete node;
		g_GetCreatureMgr()->RecycleDoubleListView((DoubleListViewData*)node->GetHost());
		g_GetCreatureMgr()->RecycleDoubleNode(node);
		return true;
	}
	return false;
}


Creature::Creature()
	: m_pos({ 0, 0, 0, })
	, m_sceneId(0)
	, m_Cid(0)
	, m_sightRange(0.0f)
	, m_creatureKind(0)
	, m_seeInterval(300)
	, m_lastSeeTime(0)
	, m_lastUpdateNineTime(0)
	//, m_fspeed(4.7f)
	, m_pMyGrid(nullptr)
	, m_gridNode(nullptr)
	, m_pScene(nullptr)
	, m_curstate(State_Init)
	, m_bCanBeSeen(true)
	, m_planeID(0)
	, m_bAttack(true)
	,  m_aiData(nullptr)
	
{
	m_lastSeeTime = 0;
	m_destory = false;
	m_attrsCache.clear();
	m_attrs64Cache.clear();
	m_attrsBroadCastCache.clear();
	m_attrs64BroadCastCache.clear();
	m_bAttack = true;
	m_aiData = nullptr;
	m_willDead = false;
}

Creature::~Creature()
{
	//if (m_pScene)
	//{
	//	LogAlwaysFmtPrint("Creature::~Creature m_pScene != nullptr: maybe Creature hasnot leave scene, cid:%ld", m_Cid);
	//	NoticeNineGridLeave();
	//	m_pScene->RemoveCreature(m_Cid);
	//}

	//if (m_pMyGrid)
	//{
	//	LogErrFmtPrint("Creature::~Creature m_pMygrid != nullptr: maybe Creature hasnot leave grid! cid:%ld", m_Cid);
	//	m_pMyGrid->RemoveCreature(this);
	//}
	m_Cid = 0;
	m_sceneId = 0;
	m_creatureKind = 0;
	m_sightRange = 10.0f;
	m_seeInterval = 1000;
	m_lastSeeTime = 0;
	m_pMyGrid = nullptr;
	m_gridNode = nullptr;
	m_pScene = nullptr;
	//m_fspeed = 0.0;
	if (m_aiData)
	{
		m_aiData->UnInit();
		g_GetBehaviacAIMgr()->DeleteAI(m_aiData);
	}
}

void Creature::Update(uint64_t tick)
{
	//UpdateSeeLst2();
	//if (IsCanSeen())
	//{
	//	if (tick - m_lastSeeTime >= m_seeInterval)
	//	{
	//		UpdateNineGridLst();
	//		m_lastSeeTime = g_GetGlobalServerTime()->Tick();
	//	}
	//}
	//这里主要是把怪物的视野同步全部去掉，所在需要在人物的视野同步做些特殊处理
	//if ((m_creatureKind == CREATURE_PLAYER )
	//	&& tick - m_lastSeeTime >= m_seeInterval)
	//{
		
	//}
	//else if (m_creatureKind == CREATURE_MONSTER   //塔主动更新视野
	//		&& tick - m_lastSeeTime >= m_seeInterval)
	//{
	//	Monster * pMonster = dynamic_cast<Monster*>(this);
	//	if (pMonster && pMonster->GetMonsterType()== ENUM_MONSTER_TYPE_BOSS_TA)
	//	{
	//		UpdateNineGridLst();
	//		m_lastSeeTime = g_GetGlobalServerTime()->Tick();
	//	}
	//}
	UpdateSummon();
}

void Creature::FindCreatureInScene(Uint64Lst& clist)
{
	//根据提供的坐标位置，找对应场景里的生物
	Scene *pScene = g_GetSceneMgr()->GetScene(m_sceneId);
	if (!pScene)
		return;
	if (m_sightRange <= 0)
		return;

	pScene->FindCreatureInScene(clist, m_pos, m_sightRange);
}

void Creature::FindSeeListInNineGride(Creature* pSrc, std::vector<Creature*>* clist, Point3<float>& srcPos)
{
	//根据提供的坐标位置，找对应场景里的生物
	if (!m_pScene)
		return;
	//if (m_sightRange <= 0)
	//	return;

	//找出玩家所在格子的中心点
	m_pScene->FindSeeLstInNineGride(pSrc, clist, m_pos);
}

void Creature::FindDoubleSeeListInNineGride(Creature* pSrc, std::vector<Creature*>& clist, Point3<float>& srcPos)
{
	//根据提供的坐标位置，找对应场景里的生物
	//Scene *pScene = g_GetSceneMgr()->GetScene(m_sceneId);
	if (!m_pScene)
		return;
	//if (m_sightRange <= 0)
	//	return;

	//找出玩家所在格子的中心点
	m_pScene->FindDoubleSeeLstInNineGride(pSrc, clist, m_pos);
}

bool Creature::ViewFliter(Creature* pCreature, float dict)
{
	if (pCreature == nullptr || GetScene() != pCreature->GetScene())
	{
		return true;
	}

	if (dict > MAX_CHARACTER_SINGLERANGE_SQUARE)
	{
		return true;
	}

	if (!GetCanBeSeenFlag() || !pCreature->GetCanBeSeenFlag())
	{
		return true;
	}

	//if (CreatureKind() != CREATURE_DROP)
	{
		//位面判断
		if ((GetPlaneID() > 0 && !g_GetPlaneMgr()->IsInPlane(GetPlaneID(), pCreature->GetCid())) ||
			(pCreature->GetPlaneID() > 0 && !g_GetPlaneMgr()->IsInPlane(pCreature->GetPlaneID(), GetCid())))
		{
			return true;
		}
	}


	return false;
}

void Creature::ReplacePVPSeeList(int relation, Creature* pCreature, std::vector<Creature*>& notifyBeenSeeLst)
{
	if (relation >= NEW_SEE_VISION_LESS_HALF_OF_HALF_MAX_SIGHT_RANGE)
	{
		return;
	}
	DoubleNode* replaceNode = nullptr;
	for(DoubleNode* node = pCreature->GetVisionData().m_doublePVPSeeLst.Tail(); node != nullptr; node = pCreature->GetVisionData().m_doublePVPSeeLst.Prev(node))
	{
		DoubleListViewData* pData = (DoubleListViewData*)node->GetHost();
		if (pData)
		{
			Creature* pOther = pData->pCreature;
			if (pOther && pOther != pCreature)
			{
				float otherDict = point2LengthSquare(pCreature->GetPos(), pOther->GetPos());
				if (otherDict > MAX_CHARACTER_SINGLERANGE_SQUARE/4.0f)
				{
					replaceNode = node;
					break;
				}
			}
		}
	}

	if (replaceNode != nullptr)
	{
		DoubleListViewData* pData = (DoubleListViewData*)replaceNode->GetHost();
		if (pData)
		{
			//Creature* pOther = m_pScene->GetCreature(pData->cid);
			Creature* pOther = pData->pCreature;
			//这里先发送摧毁， 在摧毁， pOther可能不存在, pData可能被摧毁
			if (pOther)
			{
				CreatureDestoryData CreatureDestoryData;
				CreatureDestoryData.add_cids(pCreature->GetCid());
				pOther->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&CreatureDestoryData));


				CreatureDestoryData.Clear();
					//CreatureDestoryData.add_cids(pData->cid);
				CreatureDestoryData.add_cids(pOther->GetCid());
				pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&CreatureDestoryData));
				

				pCreature->DelPVPSeeLst(replaceNode, pOther);

				SimpleAddPVPSeeLst(relation, pCreature);
				notifyBeenSeeLst.push_back(pCreature);
				CreaturesCreateData CreatureCreatureData;
				GetVisibleDataToClient(CreatureCreatureData);
				pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&CreatureCreatureData));

			}
		}
	}
}

void Creature::SimplePVMAddSeeLst(Creature* pCreature)
{
	if (pCreature == nullptr)
	{
		return;
	}

	//DoubleNode* pos = m_visionData.AddDoubleSeeList(pCreature->GetCid());
	DoubleNode* pos = m_visionData.AddPVMSeeList(pCreature);
	if (pos == nullptr)
	{
		LogAlwaysFmtPrint("m_visionData.AddDoubleSeeList failed!");
		return;
	}

	DoubleNode* pos2 = pCreature->GetVisionData().AddPVMSeeList(this);
	if (pos2 == nullptr)
	{
		LogAlwaysFmtPrint("pCreature->GetVisionData().AddDoubleSeeList failed!");
		m_visionData.DelPVMSeeList(pos);
		return;
	}

	DoubleListViewData* pData = (DoubleListViewData*)pos->GetHost();
	if (pData)
	{
		pData->nMeInHisVisionPos = pos2;
	}

	DoubleListViewData* pData2 = (DoubleListViewData*)pos2->GetHost();
	if (pData2)
	{
		pData2->nMeInHisVisionPos = pos;
	}

	if (this->CreatureKind() != CREATURE_PLAYER && m_visionData.m_doublePVMSeeLst.Count() == 1)
	{
		g_GetEvent()->FireExecute(EVENT_MONSTER_BEEN_FIRST_PLAYER_SEE, m_Cid, 0, nullptr, 0);
	}

	if (pCreature->CreatureKind() != CREATURE_PLAYER && pCreature->GetVisionData().m_doublePVMSeeLst.Count() == 1)
	{
		g_GetEvent()->FireExecute(EVENT_MONSTER_BEEN_FIRST_PLAYER_SEE, pCreature->GetCid(), 0, nullptr, 0);
	}
}

void Creature::SimpleAddPVPSeeLst(int relation, Creature* pCreature)
{
	if (pCreature == nullptr)
	{
		return;
	}

	if (m_visionData.m_doublePVPSeeLst.Count() >= MAX_SEE_CREATURE_COUNT_IN_THE_VISION)
	{
		return;
	}

	if (pCreature->m_visionData.m_doublePVPSeeLst.Count() >= MAX_SEE_CREATURE_COUNT_IN_THE_VISION)
	{
		return;
	}


	DoubleNode* pos = m_visionData.AddPVPSeeList(relation,pCreature);
	if (pos == nullptr)
	{
		LogAlwaysFmtPrint("m_visionData.AddPVPSeeList failed!");
		return;
	}

	DoubleNode* pos2 = pCreature->GetVisionData().AddPVPSeeList(relation, this);
	if (pos2 == nullptr)
	{
		LogAlwaysFmtPrint("pCreature->GetVisionData().AddPVPSeeList failed!");
		m_visionData.DelPVPSeeList(pos);
		return;
	}

	DoubleListViewData* pData = (DoubleListViewData*)pos->GetHost();
	if (pData)
	{
		pData->nMeInHisVisionPos = pos2;
	}

	DoubleListViewData* pData2 = (DoubleListViewData*)pos2->GetHost();
	if (pData2)
	{
		pData2->nMeInHisVisionPos = pos;
	}
}

void Creature::AddPVMSeeLst(Creature* pCreature, std::vector<Creature*>& vecBeen)
{
	if (pCreature == nullptr)
	{
		return;
	}

	{
		SimplePVMAddSeeLst(pCreature);
		vecBeen.push_back(pCreature);
		
		if (pCreature->CreatureKind() == CREATURE_PLAYER)
		{
			CreaturesCreateData CreatureCreatureData;
			GetVisibleDataToClient(CreatureCreatureData);
			pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&CreatureCreatureData));
		}
	}
}

void Creature::AddPVPSeeLst(int relation, Creature* pCreature, std::vector<Creature*>& vecBeen)
{
	if (pCreature == nullptr)
	{
		return;
	}

	if (m_visionData.m_doublePVPSeeLst.Count() >= MAX_SEE_CREATURE_COUNT_IN_THE_VISION)
	{
		return;
	}

	if (pCreature->m_visionData.m_doublePVPSeeLst.Count() < MAX_SEE_CREATURE_COUNT_IN_THE_VISION)
	{
		SimpleAddPVPSeeLst(relation, pCreature);
		vecBeen.push_back(pCreature);

		if (pCreature->CreatureKind() == CREATURE_PLAYER)
		{
			CreaturesCreateData CreatureCreatureData;
			GetVisibleDataToClient(CreatureCreatureData);
			pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&CreatureCreatureData));
		}
	}
	else
	{
		ReplacePVPSeeList(relation, pCreature, vecBeen);
	}
}

DoubleNode* Creature::DelPVPSeeLst(DoubleNode* delpos, Creature* pCreature)
{
	DoubleNode* pos = m_visionData.m_doublePVPSeeLst.Next(delpos);
	if (pCreature)
	{
		DoubleListViewData* pData = (DoubleListViewData*)delpos->GetHost();
		if (pData)
		{
			if (pData->nMeInHisVisionPos)
			{
				DoubleListViewData* pOtherData = (DoubleListViewData*)pData->nMeInHisVisionPos->GetHost();
				if (pOtherData && nullptr != pOtherData->pCreature && pOtherData->pCreature == this
						&& pCreature->GetVisionData().DelPVPSeeList(pData->nMeInHisVisionPos))
				{
					pData->nMeInHisVisionPos = nullptr;
				}
				else
				{
					LogErrFmtPrint("pCreature->GetVisionData().m_doublePVPSeeLst.Delete 0 failed!");
				}
			}
			else
			{
				LogErrFmtPrint("pCreature->GetVisionData().m_doublePVPSeeLst.Delete 1 failed!");
			}
		}
		else
		{
			LogErrFmtPrint("pCreature->GetVisionData().m_doublePVPSeeLst.m_doubleSeeLst 2 failed!");
		}
	}

	if (m_visionData.DelPVPSeeList(delpos) == false)
	{
		LogErrFmtPrint("m_visionData.m_doublePVPSeeLst.Delete 3 failed!");
	}
	return pos;
}

DoubleNode* Creature::DelPVMSeeLst(DoubleNode* delpos, Creature* pCreature)
{
	DoubleNode* pos = m_visionData.m_doublePVMSeeLst.Next(delpos);
	if (pCreature == nullptr)
		return nullptr;

	DoubleListViewData* pData = (DoubleListViewData*)delpos->GetHost();
	if (pData)
	{
		if (pData->nMeInHisVisionPos)
		{
			DoubleListViewData* pOtherData = (DoubleListViewData*)pData->nMeInHisVisionPos->GetHost();
			if (pOtherData && nullptr != pOtherData->pCreature && pOtherData->pCreature == this
				&& pCreature->GetVisionData().DelPVMSeeList(pData->nMeInHisVisionPos))
			{
				pData->nMeInHisVisionPos = nullptr;
			}
			else
			{
				LogErrFmtPrint("pCreature->GetVisionData().m_doublePVMSeeLst.Delete 0 failed!");
			}
		}
		else
		{
			LogErrFmtPrint("pCreature->GetVisionData().m_doublePVMSeeLst.Delete 1 failed!");
		}
	}
	else
	{
		LogErrFmtPrint("pCreature->GetVisionData().m_doublePVMSeeLst.m_doubleSeeLst 2 failed!");
	}

	if (m_visionData.DelPVMSeeList(delpos) == false)
	{
		LogErrFmtPrint("m_visionData.m_doublePVMSeeLst.Delete 3 failed!");
	}

	if (this->CreatureKind() != CREATURE_PLAYER && m_visionData.m_doublePVMSeeLst.Count() == 0)
	{
		g_GetEvent()->FireExecute(EVENT_MONSTER_NO_PLAYER_SEE, m_Cid, 0, nullptr, 0);
	}

	if (pCreature->CreatureKind() != CREATURE_PLAYER && pCreature->GetVisionData().m_doublePVMSeeLst.Count() == 0)
	{
		g_GetEvent()->FireExecute(EVENT_MONSTER_NO_PLAYER_SEE, pCreature->GetCid(), 0, nullptr, 0);
	}
	return pos;
}

void Creature::UpdateSeeLst()
{
	m_lastSeeTime = g_GetGlobalServerTime()->Tick();

	//根据提供的坐标位置，找对应场景里的生物
	 std::vector<Creature*> newPVPSeeLst[NEW_SEE_VISION_MAX];
	 std::vector<Creature*> newPVMSeeLst;
	 std::vector<Creature*> oldSeeLst;
	 std::vector<Creature*> notifyBeenSeeLst;
	 CreaturesCreateData createData;
	 CreatureDestoryData destoryData;
	Creature *pCreature = nullptr;

	for(int i = 0; i < NEW_SEE_VISION_MAX; i++)
	{
		newPVPSeeLst[i].clear();
	}

	newPVMSeeLst.clear();
	notifyBeenSeeLst.clear();
	createData.Clear();
	destoryData.Clear();
	oldSeeLst.clear();

	for(DoubleNode* node = m_visionData.m_doublePVMSeeLst.Head(); node != nullptr;)
	{
		DoubleListViewData* pData = (DoubleListViewData*)node->GetHost();
		if (pData)
		{
			pCreature = pData->pCreature;
			if (pCreature)
			{
				//这里是人跟怪的视野列表，人和怪以及怪和人是没有视野范围的，所以这里不需要计算距离
				float dict = point2LengthSquare(GetPos(), pCreature->GetPos());
				if (!ViewFliter(pCreature, dict))
				{
					pCreature->GetVisionData().chVisionUnitType = VISIONTYPE_ALREADY_IN_VISION;
					oldSeeLst.push_back(pCreature);
				}
				else
				{
					destoryData.add_cids(pData->pCreature->GetCid());
					if (pCreature->CreatureKind() == CREATURE_PLAYER)
					{
						CreatureDestoryData CreatureDestoryData;
						CreatureDestoryData.add_cids(m_Cid);
						pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&CreatureDestoryData));
					}
					node = DelPVMSeeLst(node, pCreature);
					continue;
				}
			}
			else
			{
				LogAlwaysFmtPrint("m_visionData.m_doubleSeeLst can't find the node:%p in the scene!", node);
				//destoryData.add_cids(pData->cid);
				node = DelPVMSeeLst(node, pCreature);
				continue;
			}
		}
		else
		{
			LogAlwaysFmtPrint("m_visionData.m_doubleSeeLst.GetHost failed!");
		}

		node = m_visionData.m_doublePVMSeeLst.Next(node);
	}

	if (CreatureKind() == CREATURE_PLAYER)
	{
		for(DoubleNode* node = m_visionData.m_doublePVPSeeLst.Head(); node != nullptr;)
		{
			DoubleListViewData* pData = (DoubleListViewData*)node->GetHost();
			if (pData)
			{
				pCreature = pData->pCreature;
				if (pCreature && pCreature->CreatureKind() == CREATURE_PLAYER)
				{
					//ActorRockerMove rockmove;
					//GetRockeMoveDataToClient(rockmove);
					//if (rockmove.cid() > 0)
					//{
					//	pCreature->SendDataToClient(LOGIC_TO_CLIENT_ACTOR_ROCKER_MOVE, &rockmove);
					//	//cout << "==========semd rocker move data=======" << rockmove.DebugString() << endl;
					//}

					float dict = point2LengthSquare(GetPos(), pCreature->GetPos());
					if (!ViewFliter(pCreature, dict))
					{
						pCreature->GetVisionData().chVisionUnitType = VISIONTYPE_ALREADY_IN_VISION;
						oldSeeLst.push_back(pCreature);
					}
					else
					{
						//destoryData.add_cids(pData->cid);
						destoryData.add_cids(pCreature->GetCid());
						if (pCreature->CreatureKind() == CREATURE_PLAYER)
						{
							CreatureDestoryData CreatureDestoryData;
							CreatureDestoryData.add_cids(m_Cid);
							pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&CreatureDestoryData));
						}
						node = DelPVPSeeLst(node, pCreature);
						continue;
					}
				}
				else
				{
					LogAlwaysFmtPrint("m_visionData.m_doublePVPSeeLst can't find the pos in the scene!");
					//destoryData.add_cids(pData->cid);
					node = DelPVPSeeLst(node, pCreature);
					continue;
				}
			}
			else
			{
				LogAlwaysFmtPrint("m_visionData.m_doublePVPSeeLst.GetObject failed!");
			}
			node = m_visionData.m_doublePVPSeeLst.Next(node);
		}

		if (m_visionData.m_doublePVPSeeLst.Count() < MAX_SEE_CREATURE_COUNT_IN_THE_VISION)
		{
			FindSeeListInNineGride(this, newPVPSeeLst, GetPos());

			for (int i = NEW_SEE_VISION_SPECIAL_RELATIONSHIP; i < NEW_SEE_VISION_MAX; i++)
			{
				for (auto it = newPVPSeeLst[i].begin(); it != newPVPSeeLst[i].end(); it++)
				{
					pCreature = *it;
					if (pCreature && pCreature->GetCid() != m_Cid)
					{
						AddPVPSeeLst(i, pCreature, notifyBeenSeeLst);

						if (m_visionData.m_doublePVPSeeLst.Count() >= MAX_SEE_CREATURE_COUNT_IN_THE_VISION)
						{
							break;
						}
					}
				}
			}
		}
	} // end of if (CreatureKind() == CREATURE_PLAYER)

	FindDoubleSeeListInNineGride(this, newPVMSeeLst, GetPos());

	for (std::vector<Creature*>::iterator it = newPVMSeeLst.begin(); it != newPVMSeeLst.end(); it++)
	{
		pCreature = *it;
		if (pCreature && pCreature->GetCid() != m_Cid)
		{
			AddPVMSeeLst(pCreature, notifyBeenSeeLst);
		}
	}

	for(int i = 0; i < (int)oldSeeLst.size(); i++)
	{
		oldSeeLst[i]->GetVisionData().chVisionUnitType = VISIONTYPE_NONE;
	}

	//这里通知客户端删除生物 并且做视野移除
	if (CreatureKind() == CREATURE_PLAYER && destoryData.cids_size() > 0)
	{
		SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&destoryData));
	}

	//有新的生物进入视野
	if (CreatureKind() == CREATURE_PLAYER && !notifyBeenSeeLst.empty())
	{
		uint32_t count=0;
		//先让客户端创建生物实体，再执行该生物的被见逻辑
		for (auto iter = notifyBeenSeeLst.begin(); iter != notifyBeenSeeLst.end(); iter++)
		{
			//通知自己的角色属性信息
			pCreature = *iter;

			//再将对方加入到我自己的视野中
			if (pCreature)
			{
				pCreature->GetVisibleDataToClient(createData);
			}
			count ++;
			if (count>g_constSendClientCreatureNum)
			{
				SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&createData));
				createData.Clear();
				count = 0;
			}
		}
		if (createData.ByteSize()>0)
		{
			SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&createData));
		}
	}
}

//用于重连上后，再重新发送一次全体视野信息。
void Creature::SendAllSeeCreatureListToClient()
{
	uint32_t count = 0;
	CreaturesCreateData createData;
	Creature * pCreature = nullptr;
	std::vector<Creature*> vList = GetCreatureList();
	//先让客户端创建生物实体，再执行该生物的被见逻辑
	for (auto iter = vList.begin(); iter != vList.end(); iter++)
	{
		//通知自己的角色属性信息
		pCreature = *iter;

		//再将对方加入到我自己的视野中
		if (pCreature)
		{
			pCreature->GetVisibleDataToClient(createData);
		}
		count++;
		if (count > g_constSendClientCreatureNum)
		{
			SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&createData));
			createData.Clear();
			count = 0;
		}
	}
	if (createData.ByteSize() > 0)
	{
		SendDataToClient(LOGIC_TO_CLIENT_CREATURE_CREATE, (ProtoBufBase*)(&createData));
	}
}


void Creature::UpdateNineGridLst()
{
	UpdateSeeLst();
}


std::vector<Creature*> Creature::GetCreatureList()
{
	std::vector<Creature*> vec;

	if (CreatureKind() == CREATURE_PLAYER)
	{
		for (DoubleNode* pNode = m_visionData.m_doublePVPSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVPSeeLst.Next(pNode))
		{
			DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
			if (pNode && nullptr != pData->pCreature)
			{
				vec.push_back(pData->pCreature);
			}
		}
	}

	for (DoubleNode* pNode = m_visionData.m_doublePVMSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVMSeeLst.Next(pNode))
	{
		DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
		if (pNode && nullptr != pData->pCreature)
		{
			vec.push_back(pData->pCreature);
		}
	}

	return vec;
}


std::vector<CharIDType> Creature::GetSeeLst()
{
	std::vector<CharIDType> vec;

	if (CreatureKind() == CREATURE_PLAYER)
	{
		for(DoubleNode* pNode = m_visionData.m_doublePVPSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVPSeeLst.Next(pNode))
		{
			DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
			if (pNode && nullptr != pData->pCreature)
			{
				vec.push_back(pData->pCreature->GetCid());
			}
		}
	}

	for(DoubleNode* pNode = m_visionData.m_doublePVMSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVMSeeLst.Next(pNode))
	{
		DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
		if (pNode && nullptr != pData->pCreature)
		{
			vec.push_back(pData->pCreature->GetCid());
		}
	}

	return vec;
}

void Creature::GetSeeLst(std::vector<CharIDType>& vec)
{
	if (CreatureKind() == CREATURE_PLAYER)
	{
		for(DoubleNode* pNode = m_visionData.m_doublePVPSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVPSeeLst.Next(pNode))
		{
			DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
			if (pNode && nullptr != pData->pCreature)
			{
				vec.push_back(pData->pCreature->GetCid());
			}
		}
	}

	for(DoubleNode* pNode = m_visionData.m_doublePVMSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVMSeeLst.Next(pNode))
	{
		DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
		if (pNode && nullptr != pData->pCreature)
		{
			vec.push_back(pData->pCreature->GetCid());
		}
	}
}

void Creature::NoticeNineGridLeave()
{
	if (CreatureKind() == CREATURE_PLAYER)
	{
		for(DoubleNode* pNode = m_visionData.m_doublePVPSeeLst.Head(); pNode != nullptr; )
		{
			DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
			if (pData)
			{
				Creature * pCreature = pData->pCreature;
				if (pCreature)
				{
					pCreature->GetVisionData().DelPVPSeeList(pData->nMeInHisVisionPos);
					//通知删除
					CreatureDestoryData destoryData;
					destoryData.add_cids(m_Cid);
					pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&destoryData));
				}
				DoubleNode* delPos = pNode;
				pNode = m_visionData.m_doublePVPSeeLst.Next(pNode);
				m_visionData.DelPVPSeeList(delPos);
				//delete delPos;
				continue;
			}
			else
			{
				DoubleNode* delPos = pNode;
				pNode = m_visionData.m_doublePVPSeeLst.Next(pNode);
				//delete delPos;
				m_visionData.DelPVPSeeList(delPos);
				continue;
			}
		}
	}
	for(DoubleNode* pNode = m_visionData.m_doublePVMSeeLst.Head(); pNode != nullptr; )
	{
		DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
		if (pData)
		{
			Creature * pCreature = pData->pCreature;
			if (pCreature)
			{
				pCreature->GetVisionData().DelPVMSeeList(pData->nMeInHisVisionPos);

				//send event, stop monster ai
				if (pCreature->CreatureKind() != CREATURE_PLAYER && pCreature->GetVisionData().m_doublePVMSeeLst.Count() == 0)
				{
					g_GetEvent()->FireExecute(EVENT_MONSTER_NO_PLAYER_SEE, pCreature->GetCid(), 0, nullptr, 0);
				}

				if (pCreature->CreatureKind() == CREATURE_PLAYER)
				{
					bool isNoticeClient = false;
					if (CreatureKind() == CREATURE_MONSTER)
					{
						Monster * pMonster = dynamic_cast<Monster*>(this);
						if (pMonster)
						{
							if (pMonster->IsDead() && pMonster->IsCanBoPi())
							{
								isNoticeClient = true;
							}
						}
					}

					if (isNoticeClient)
					{
						//通知删除
						CreatureDestoryData destoryData;
						destoryData.add_cids(m_Cid);
						pCreature->SendDataToClient(LOGIC_TO_CLIENT_CREATURE_DESTORY, (ProtoBufBase*)(&destoryData));
					}
				}
				
			}
			DoubleNode* delPos = pNode;
			pNode = m_visionData.m_doublePVMSeeLst.Next(pNode);
			//delete delPos;
			m_visionData.DelPVMSeeList(delPos);
			continue;
		}
		else
		{
			DoubleNode* delPos = pNode;
			pNode = m_visionData.m_doublePVMSeeLst.Next(pNode);
			//delete delPos;
			m_visionData.DelPVMSeeList(delPos);
			continue;
		}
	}
}

bool Creature::BroadCastData(uint16_t cmd, ProtoBufBase* buf, bool IncludeMyself /* = false */)
{
	return BroadCastData(EMODULE_ID_PLAYER, cmd, buf, IncludeMyself);
}

bool Creature::BroadCastData(uint16_t module, uint16_t cmd, ProtoBufBase* buf, bool IncludeMyself /*= false*/)
{
	
	if (m_creatureKind == CREATURE_PLAYER && !IsCanSendMessage())
	{
		return false;
	}

	//SET_UINT64 charSets;
	//LIST_UINT32 lstClientids;
	uint32_t clientId = 0;
	uint32_t gateId = 0;

	MAP_UINT32_LST_UINT32 gateClientsMap;
	if (IncludeMyself && m_creatureKind == CREATURE_PLAYER)
	{
		dynamic_cast<Player*>(this)->GetGateClientId(gateId, clientId);
		LIST_UINT32& lstClientids = gateClientsMap[gateId];
		lstClientids.push_back(clientId);
	}

	if (CreatureKind() == CREATURE_PLAYER)
	{
		for(DoubleNode* pNode = m_visionData.m_doublePVPSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVPSeeLst.Next(pNode))
		{
			DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
			if (pData)
			{
				//Player* pPlayer = g_GetCreatureMgr()->GetPlayer(pData->cid);
				if (nullptr != m_pScene)
				{
					if (nullptr != pData->pCreature && pData->pCreature->CreatureKind() == CREATURE_PLAYER)
					{
						Player *pPlayer = dynamic_cast<Player*>(pData->pCreature);
						if (pPlayer && pPlayer->IsCanSendMessage())
						{
							pPlayer->GetGateClientId(gateId, clientId);

							LIST_UINT32& lstClientids = gateClientsMap[gateId];
							lstClientids.push_back(clientId);

							if (lstClientids.size()>g_constSendClientCreatureNum)  //超过指定人数，先发出去，这个人数可调
							{
								g_GetLogicService()->SendDataToClient(gateId, lstClientids, module, cmd, buf);

								lstClientids.clear();
								gateClientsMap.erase(gateId);
							}
						}
					}

				/*	Player *pPlayer = m_pScene->GetPlayer(pData->cid);
					if (pPlayer && pPlayer->IsCanSendMessage())
					{
						lstClientids.push_back(pPlayer->GetClientId());
					}*/
				}
			}
		}
	}
	else
	{

		for(DoubleNode* pNode = m_visionData.m_doublePVMSeeLst.Head(); pNode != nullptr; pNode = m_visionData.m_doublePVMSeeLst.Next(pNode))
		{
			DoubleListViewData* pData = (DoubleListViewData*)pNode->GetHost();
			if (pData)
			{
				//Player* pPlayer = g_GetCreatureMgr()->GetPlayer(pData->cid);
				if (nullptr != m_pScene)
				{
					if (nullptr != pData->pCreature)
					{
						Player *pPlayer = dynamic_cast<Player*>(pData->pCreature);
						if (pPlayer && pPlayer->IsCanSendMessage())
						{
							pPlayer->GetGateClientId(gateId, clientId);
							LIST_UINT32& lstClientids = gateClientsMap[gateId];
							lstClientids.push_back(clientId);

							if (lstClientids.size() > g_constSendClientCreatureNum)  //超过指定人数，先发出去，这个人数可调
							{
								g_GetLogicService()->SendDataToClient(gateId, lstClientids, module, cmd, buf);
								lstClientids.clear();
								gateClientsMap.erase(gateId);
							}
						}
					}
				}
			}
		}
	}
	if (gateClientsMap.size()>0)
	{
		g_GetLogicService()->SendDataToClient(gateClientsMap, module, cmd, buf);
		return true;
	}
	else
	{
		return false;
	}
}

//判断是否能发送消息
bool Creature::IsCanSendMessage()
{
	AccountGameState accountState = GetAccountState();
	if (m_creatureKind != CREATURE_PLAYER || accountState == ACCOUNT_GAME_STATE_DISCONNECT || accountState == ACCOUNT_GAME_STATE_LOGOUT)
		return false;
	return true;
}

bool Creature::SendDataToClient(uint16_t cmd, ProtoBufBase* buf)
{
	if (!IsCanSendMessage())
	{
		return false;
	}

	uint32_t clientId = 0;
	uint32_t gateId = 0;
	GetGateClientId(gateId, clientId);
	return g_GetLogicService()->SendDataToClient(gateId, clientId, EMODULE_ID_PLAYER, cmd, buf);
}

bool Creature::SendDataToClient(uint16_t module, uint16_t cmd, ProtoBufBase* buf)
{
	if (!IsCanSendMessage())
	{
		return false;
	}

	uint32_t clientId = 0;
	uint32_t gateId = 0;
	GetGateClientId(gateId, clientId);
	return g_GetLogicService()->SendDataToClient(gateId, clientId, module, cmd, buf);
}

bool Creature::SendDataToClientEx(uint16_t module, uint16_t cmd, ProtoBufBase* buf)
{
	return SendDataToClient(module, cmd, buf);
}

bool Creature::EnterScene(uint32_t sceneId, Point3<float>& enterPos, STransParam &transParam)
{
	if (m_pScene)
	{
		if (m_pScene->GetSceneId() == sceneId)
			return false;
		if (!m_pScene->LeaveScene(m_Cid, m_pMyGrid))
			return false;
	}

	m_pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (!m_pScene)
		return false;

	m_pMyGrid = m_pScene->EnterScene(m_Cid, enterPos, this, transParam);
	if (!m_pMyGrid)
		return false;

	m_pos = enterPos;
	m_sceneId = sceneId;
	m_mapId = m_pScene->GetMapId();

	UpdateNineGridLst();

	return true;
}

bool Creature::LeaveScene()
{
	//场景为空直接返回
	if (!m_pScene)
		return false;
	Scene *pScene = g_GetSceneMgr()->GetScene(m_sceneId);
	if (!pScene)
		return false;
	if (!pScene->LeaveScene(m_Cid, m_pMyGrid))
		return false;

	m_pMyGrid = nullptr;
	m_pScene = nullptr;
	
	return true;
}

float  Creature::GetSpeed()  
{
	//return m_fspeed;
	int64_t speed = GetAttr(C_MSPEED);
	float tmpSpeed = speed / 1000.0f;
	return tmpSpeed;
}
void   Creature::SetSpeed(float f, bool isSync)
{
	//m_fspeed = f;
	//if (isSync)
	{
		SetAttr(g_GetAttrMgr()->GetLevCNumAttr(m_creatureKind,C_MSPEED), f * 1000,isSync);
	}


	//LogDebugFmtPrint("set speed  = %f cid=%llu,issync=%d",f,m_Cid,isSync);
}

bool Creature::Init()
{
	//g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), 0, m_Cid, 0, NULL);
	return true;
}

bool Creature::UnInit()
{
	//g_GetEvent()->UnSubscribeAll(dynamic_cast<IEventExecuteSink*>(this));
	//g_GetTimerAxis()->KillAllTimer(this);
	//g_GetTimerAxis()->KillAllFixTimer(this);
	return true;
}

void Creature::OnDead(CharIDType killerCid)
{
	m_curstate = State_dead;
	m_attrsBroadCastCache[M_HP] = 0;
	SynAttrToClient();
	//CharIDType nSrcId = 0;
	//DieEvent dieEvent;
	//dieEvent.killerCid = killerCid;
	//dieEvent.count = 1;
	//dieEvent.sceneId = m_sceneId;
	//dieEvent.nCid = m_Cid;
	//if (m_creatureKind == CREATURE_MONSTER)
	//{
	//	nSrcId = killerCid;
	//	dieEvent.monsterId = GetConfigId();
	//	//获取该怪物仇恨列表的人
	//	Monster* pMonster = dynamic_cast<Monster*>(this);
	//	if (nullptr != pMonster)
	//	{
	//		pMonster->GetHateListID(dieEvent.hateTargetList);
	//	}
	//}
	//else if (m_creatureKind == CREATURE_PLAYER)
	//{
	//	nSrcId = m_Cid;
	//}
	//g_GetEvent()->FireExecute(EVENT_CREATURE_DEAD, nSrcId, m_creatureKind, (DieEvent*)&dieEvent, sizeof(dieEvent));

	//LogAlwaysFmtPrint("creature ondead, cid:%d, monsterId:%u ", m_Cid,dieEvent.monsterId);
}

void Creature::OnCorpse()
{

}

void Creature::OnRevive(CharIDType saverCid)
{
	m_curstate = State_normal;
	m_attrBroadcastClient.set_cid(m_Cid);
	m_attrBroadcastClient.set_curstate(state_relive);
	//LogAlwaysFmtPrint("creature revive, cid:%d", m_Cid);
	BroadCastData(LOGIC_TO_CLIENT_CREATURE_SYN_ATTR_ALL, (ProtoBufBase*)&m_attrBroadcastClient, true);
	if (m_creatureKind == CREATURE_PLAYER)
	{
		//复活状态通知到中心服
		GWLifeStatusNotify notify;
		notify.set_charid(m_Cid);
		notify.set_lifestatus(state_relive);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_SERV_SYS, LOGIC_TO_CENTER_LIFE_STATUS_NOTIFY, &notify);

	}
	m_attrBroadcastClient.Clear();
}

void Creature::SetPos(Point3<float>& pos)
{
	//LogAlwaysFmtPrint("set pos cid=%llu ,time1=%llu", m_Cid, Time::Tick());
	Grid *pGrid = nullptr;
	bool isSameGrid = false;
	if (!m_pScene || IsDestory())
	{
		return;
	}

	Point2<uint32_t> newLittleGrid;
	newLittleGrid.x = pos.x / 3;
	newLittleGrid.y = pos.z / 3;

	pGrid = m_pScene->MoveInScene(m_Cid, m_pMyGrid, pos, isSameGrid);
	if (pGrid)
	{
		//float dict = point2LengthSquare(m_pos, pos);
		m_pMyGrid = pGrid;
		m_pos = pos;


		m_lastUpdateNineTime = g_GetGlobalServerTime()->Tick();;
		if (!isSameGrid)
		{
			UpdateNineGridLst();
		}
		else
		{
			if (m_littleGrid != newLittleGrid)
			{
				m_littleGrid = newLittleGrid;
//				if (g_GetGlobalServerTime()->Tick() - m_lastSeeTime < 1000)
//				{
//					return;
//				}

				UpdateSeeLst();
			}
		}
	}

	//LogAlwaysFmtPrint("set pos cid=%llu ,time2=%llu", m_Cid, Time::Tick());
}

void Creature::SynAttrToClient()
{
	if (!m_attrsBroadCastCache.empty() 
		|| m_attrBroadcastClient.has_curstate() 
		|| m_attrBroadcastClient.has_name()
		|| m_attrBroadcastClient.creatureattrs_size() > 0
		|| !m_attrs64BroadCastCache.empty())
	{

		m_attrBroadcastClient.set_cid(m_Cid);
		m_attrBroadcastClient.set_curstate(m_curstate);
		auto iter = m_attrsBroadCastCache.begin();
		for (; iter != m_attrsBroadCastCache.end(); iter++)
		{
			Attr *pAttr = m_attrBroadcastClient.add_creatureattrs();
			pAttr->set_attrnum(iter->first);
			pAttr->set_attrvalue(iter->second);
			//LogDebugFmtPrint("broad attrid=%d,attrValue=%llu m_cid=%llu",iter->first,iter->second,m_Cid);
		}

		auto iter64 = m_attrs64BroadCastCache.begin();
		for (; iter64 != m_attrs64BroadCastCache.end(); iter64++)
		{
			Attr64 *pAttr64 = m_attrBroadcastClient.add_creatureattrs64();
			pAttr64->set_attrnum(iter64->first);
			pAttr64->set_attrvalue(iter64->second);
		}

		BroadCastData(EMODULE_ID_PLAYER,LOGIC_TO_CLIENT_CREATURE_SYN_ATTR_ALL, (ProtoBufBase*)(&m_attrBroadcastClient),true);
		m_attrBroadcastClient.Clear();
		m_attrsBroadCastCache.clear();
		m_attrs64BroadCastCache.clear();
	}
}

bool Creature::TransScene(uint32_t scenceId, Point3<float>& dstPos, uint32_t mapId,STransParam &transParam)
{
	//非玩家的传送只在同一个逻辑服中
	//EnterScene(scenceId, dstPos);
	//LogAlwaysFmtPrint("this creature cant tranScene, because havnt movepart or havnt func TransScene in objclass, ckid:%d, cid:%d", m_creatureKind, m_Cid);
	return true;
}

// 分帧任务处理函数
// 返回值，任务是否完成
bool Creature::DoTask(TaskNodeId type, void* data, uint32_t size)
{
	return true;
}

bool Creature::HasBuffState(CreatureBuffStateIndex state) const
{
	return m_buffState.GetState(state);
}

void Creature::AddBuffState(CreatureBuffStateIndex state)
{
	m_buffState.AddState(state);
}

void Creature::RemoveBuffState(CreatureBuffStateIndex state)
{
	m_buffState.RemoveState(state);
}

bool  Creature::HasBuffStateNoMove() const //因为中了特殊的buff，不能移动,比如眩晕，冰冻
{
	if (m_buffState.GetState(CREATURE_BUFF_STATE_DIZZY) ||
		m_buffState.GetState(CREATURE_BUFF_STATE_FROZEN) ||
		m_buffState.GetState(CREATURE_BUFF_STATE_WINDING) ||
		m_buffState.GetState(CREATURE_BUFF_STATE_MABI))
	{
		return true;
	}
	return false;
}

bool  Creature::HasBuffStateNoSkill() const //因为中了特殊的buff，不能使用技能
{
	if (m_buffState.GetState(CREATURE_BUFF_STATE_DIZZY) ||
		m_buffState.GetState(CREATURE_BUFF_STATE_FROZEN) ||
		m_buffState.GetState(CREATURE_BUFF_STATE_MABI) ||
		m_buffState.GetState(CREATURE_BUFF_STATE_CANNOT_USE_SKILL))
	{
		return true;
	}
	return false;
}

bool Creature::HasBuffStateRefixSkill() const //因为修改技能的BUFF
{
	if (m_buffState.GetState(CREATURE_BUFF_STATE_REFIX_SKILL))
	{
		return true;
	}
	return false;
}

bool  Creature::HasBuffStateReduceDamage() const //因为中了特殊的buff，比如生命盾,可以在不加属性的情况下，影响对玩家的伤害
{
	if (m_buffState.GetState(CREATURE_BUFF_STATE_HP_SHIELD)
			|| m_buffState.GetState(CREATURE_BUFF_STATE_WUDI)
			|| m_buffState.GetState(CREATURE_BUFF_STATE_REDUCE_EXTRA_DAMAGE))
	{
		return true;
	}
	return false;
}

bool Creature::HasBuffStateAddExtraDamage() const
{
	if (m_buffState.GetState(CREATURE_BUFF_STATE_ADD_EXTRA_DAMAGE))
	{
		return true;
	}
	return false;
}

bool Creature::HasBuffStateNoAiControl() const
{
	if (HasBuffState(CREATURE_BUFF_STATE_DIZZY) ||
		HasBuffState(CREATURE_BUFF_STATE_FROZEN) ||
		HasBuffState(CREATURE_BUFF_STATE_WINDING) ||
		HasBuffState(CREATURE_BUFF_STATE_MABI))
	{
		return true;
	}
	return false;
}

void Creature::UpdateAiInfo(uint64_t deltaTime)
{
//	if (m_aiData && !m_destory)
//	{
//		m_aiData->Update();
//	}
}

void Creature::BuffEffect_CleanupAllFadeOutEffects(BuffInfoEndType endType)
{
	
}

bool Creature::BeenSeeByPlayer()
{
	if (CreatureKind() == CREATURE_PLAYER)
	{
		if (m_visionData.m_doublePVPSeeLst.Count() > 0)
		{
			return true;
		}
	}
	else
	{
		if (m_visionData.m_doublePVMSeeLst.Count() > 0)
		{
			return true;
		}
	}

	return false;
}

void Creature::SetDir(const Point3<float>& point)
{
	float length = point.length();
	if (length != 0.0f)
	{
		m_dir = point / length;
	}
}

//bool Creature::GetFormula(string str, VEC_INT32 &vOutParam)  const
//{
//	//std::string strDameage = funcAttackValue[damageCount];
//	CommonApi::StrReplace(str, ",<", "");
//	CommonApi::StrReplace(str, "<", "");
//	CommonApi::StrReplace(str, "(", "");
//	CommonApi::StrReplace(str, ")", "");
//	str = CommonApi::StrLTrim(str);
//	str = CommonApi::StrRTrim(str);
//
//	CommonApi::SplitStrToVecInt(str, ",", &vOutParam);
//	return true;
//}


bool Creature::IsExistSummon()
{
	return !m_summons.empty();
}

void Creature::AddSummon(CharIDType summonCid)
{
	Monster* pSummon = g_GetCreatureMgr()->GetMonster(summonCid);
	if (pSummon && pSummon->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
	{
		m_summons.push_back(summonCid);
	}
}

void Creature::DelSummon(CharIDType summonCid)
{
	m_summons.remove(summonCid);
}

std::vector<Monster*> Creature::GetSummons()
{
	std::vector<Monster*> vec;
	for(auto iter = m_summons.begin(); iter != m_summons.end(); iter++)
	{
		Monster* pSummon = g_GetCreatureMgr()->GetMonster(*iter);
		if (pSummon)
		{
			vec.push_back(pSummon);
		}
	}
	return vec;
}

void Creature::UpdateSummon()
{
	for(auto iter = m_summons.begin(); iter != m_summons.end();)
	{
		Monster* pSummon = g_GetCreatureMgr()->GetMonster(*iter);
		if (pSummon && !pSummon->IsDead())
		{
			if (pSummon->GetScene() == nullptr || pSummon->GetScene() != GetScene())
			{
				pSummon->SetAttr(C_HP, 0, true);
				iter = m_summons.erase(iter);
				continue;
			}
		}
		else
		{
			iter = m_summons.erase(iter);
			continue;
		}
		iter++;
	}
}

void Creature::AddSummonHateCid(CharIDType targetCid)
{
	if (GetScene() == nullptr || m_summons.empty())
	{
		return;
	}
	Creature* pTarget = GetScene()->GetCreature(targetCid);
	if (pTarget == nullptr || pTarget->IsDead())
	{
		return;
	}

	for(auto iter = m_summons.begin(); iter != m_summons.end(); iter++)
	{
		Monster* pSummon = g_GetCreatureMgr()->GetMonster(*iter);
		if (pSummon && !pSummon->IsDead())
		{
			if (pSummon->GetScene() != nullptr && pSummon->GetScene() == GetScene() && !pSummon->IsFriendSide(pTarget))
			{
				auto pAi = pSummon->GetAiData();
				if (pAi)
				{
					pAi->AddHateTarget(targetCid, 0, 0);
				}
			}
		}
	}
}


void Creature::SetCanBeSeenFlag(bool isCanBeSeen)
{
	m_bCanBeSeen = isCanBeSeen;
}
void Creature::SetPlaneID(uint64_t planeID)
{
	m_planeID = planeID;
}
bool Creature::GetCanBeSeenFlag()
{
	return m_bCanBeSeen;
}
uint64_t Creature::GetPlaneID()
{
	return m_planeID;
}


void Creature::SetBeAttackFlag(bool bFlag)
{
	m_bAttack = bFlag;
}
bool Creature::GetBeAttackFlag()
{
	return m_bAttack;
}

//是否能被打区域
bool     Creature::IsCanBeAttackByCurrentPos()
{
	//先找到该地图上的安全区域
	std::vector<uint32_t> vID;
	g_GetMapLocationCfg()->GetAreaIdByMap(m_mapId, vID);
	for (std::vector<uint32_t>::iterator iter = vID.begin(); iter != vID.end(); ++iter)
	{
		const AreaAreaCfgInfo * pArea = g_GetAreaAreaCfgTable()->GetAreaAreaCfgInfo(*iter);
		if (pArea)
		{
			if (pArea->safeAreaType == en_AreaType_Neutrality)
			{
				if (g_GetMapLocationCfg()->InArea(*iter, m_pos))
				{
					return false;
				}
			}
			else if (pArea->safeAreaType == en_AreaType_Light && GetAttr(C_CAMP_ID) != ECamp_Type_Dark)
			{
				if (g_GetMapLocationCfg()->InArea(*iter, m_pos))
				{
					return false;
				}
			}
			else if (pArea->safeAreaType == en_AreaType_Black && GetAttr(C_CAMP_ID) != ECamp_Type_Light)
			{
				if (g_GetMapLocationCfg()->InArea(*iter, m_pos))
				{
					return false;
				}
			}
		}
	}

	return true;
}


void Creature::AddSourceAttr(uint32_t CANum, int64_t value, bool sync,ItemOrCurrencySource sourType)
{
	//AddAttr(CANum, value, sync);

	const char* currencyName = g_GetAttrMgr()->GetCurrencyName(CANum);
	if (currencyName == NULL)
	{
		LogErrFmtPrint("Player::CurrencyGetLog, AttrId is not currencyType, AttrId:%d", CANum);
		return;
	}

	//通知运营平台
	Player* pPlayer = dynamic_cast<Player*>(this);
	if (pPlayer == nullptr)
	{
		LogErrFmtPrint("Creature::AddSourceAttr, pPlayer == null, %d", CANum);
		return;
	}

	uint32_t PANum = g_GetAttrMgr()->GetPAttr(CANum);
	uint64_t preValue = pPlayer->GetPAttrValue(PANum);
	pPlayer->AddAttrPA(PANum, value, sync);
	uint64_t newValue = pPlayer->GetPAttrValue(PANum);

	if (value > 0)
		pPlayer->CurrencyLog(TID_CURRENCY_GET, CANum, value, (uint32_t)sourType, currencyName, preValue, newValue);
	else
		pPlayer->CurrencyLog(TID_CURRENCY_DEL, CANum, -value, (uint32_t)sourType, currencyName, preValue, newValue);

	if (CANum == C_DIAMOND && value<0)
	{
		//发送消耗钻石事件
		CostDiamondEvent costDiamondEvent;
		costDiamondEvent.costDiamond = value;
		costDiamondEvent.source = sourType;
		g_GetEvent()->FireExecute(EVENT_COST_DAIAMOND, m_Cid, m_creatureKind,&costDiamondEvent, sizeof(CostDiamondEvent));
	}
	else if (CANum == C_DIAMOND_BIND && value<0)
	{
		//发送消耗钻石事件
		CostBindDiamondEvent costDiamondEvent;
		costDiamondEvent.costBindDiamond = value;
		costDiamondEvent.source = sourType;
		g_GetEvent()->FireExecute(EVENT_COST_BINDDAIAMOND, m_Cid, m_creatureKind, &costDiamondEvent, sizeof(CostDiamondEvent));
	}

	//成就定制事件
	if (CANum == C_DIAMOND || CANum == C_GOLD)
	{
		MoneyChangeEvent moneyChangeEvent;
		moneyChangeEvent.attrId = CANum;
		moneyChangeEvent.value = value;
		moneyChangeEvent.source = sourType;
		g_GetEvent()->FireExecute(EVENT_MONEY_CHANGE, m_Cid, m_creatureKind, &moneyChangeEvent, sizeof(MoneyChangeEvent));
	}
	
}